class Resource{
    private boolean isEmpty01 = true;
    private boolean isEmpty02 = false;
    private boolean isEmpty03 = false;
     
    //每个put方法对应一个输出，每输出一个就等待，等待其他人的唤醒
    public void put1(){
        while(!isEmpty01){
            try{
                wait();
            }catch(InterruptedException e){
                e.printStackTrace();
            }
        }
        //输出后
        isEmpty01 = false;
        isEmpty02 = true;
        notifyAll();
    }
    public void put2(){
        while(!isEmpty02){
            try{
                wait();
            }catch(InterruptedException e){
                e.printStackTrace();
            }
        }
        isEmpty02 = false;
        isEmpty03 = true;
        notifyAll();
    }
    public void put3(){
        while(!isEmpty03){
            try{
                wait();
            }catch(InterruptedException e){
                e.printStackTrace();
            }
        }
        isEmpty03 = false;
        isEmpty01 = true;
        notifyAll();
    }
}
 
class Player01 implements Runnable{
     
    private Resource res;
    private String[] arr;
    Player01(){}
    Player01(String[] arr,Resource res){
        this.arr = arr;
        this.res = res;
    }
     
    public void run(){
        synchronized(res){
            for(int i=0;i<arr.length;i++){
                //错误的点
                //61,62,这两句不能交换顺序
                res.put1();
                System.out.print(arr[i]+"-");
                try{
                    Thread.sleep(1000);
                }catch(InterruptedException e){
                    e.printStackTrace();
                }
            }
        }
    }
}
 
class Player02 implements Runnable{
     
    private Resource res;
    private String[] arr;
    Player02(){}
    Player02(String[] arr,Resource res){
        this.arr = arr;
        this.res = res;
    }
     
    public void run(){
        synchronized(res){
            for(int i=0;i<arr.length;i++){
                res.put2();
                System.out.print(arr[i]+"-");
                try{
                    Thread.sleep(1000);
                }catch(InterruptedException e){
                    e.printStackTrace();
                }
            }
        }  
    }
}
 
class Player03 implements Runnable{
     
    private Resource res;
    private String[] arr;
    Player03(){}
    Player03(String[] arr,Resource res){
        this.arr = arr;
        this.res = res;
    }
     
    public void run(){
        synchronized(res){
            for(int i=0;i<arr.length;i++){
                res.put3();
                System.out.print(arr[i]+"## ");
                try{
                    Thread.sleep(1000);
                }catch(InterruptedException e){
                    e.printStackTrace();
                }
            }
        }
    }
}
 
class MultiThreadTest {
     
    public static void main(String[] args){
         
        String[] arr1 = {"1","3","5","7","9"};
        String[] arr2 = {"a","b","c","d","e"};
        String[] arr3 = {"2","4","6","8","0"};
         
        Resource res = new Resource();
         
        Player01 p1 = new Player01(arr1,res);
        Player02 p2 = new Player02(arr2,res);
        Player03 p3 = new Player03(arr3,res);
         
        Thread t1 = new Thread(p1);
        Thread t2 = new Thread(p2);
        Thread t3 = new Thread(p3);
         
        t1.start();
        t2.start();
        t3.start();
    }
}